bookwiz.io / app / api / chat / messages / [messageId] / route.ts
route.ts
Raw
import { NextRequest, NextResponse } from 'next/server'
import { createServerSupabaseClient } from '@/lib/supabase'

export async function DELETE(
  req: NextRequest,
  { params }: { params: { messageId: string } }
) {
  try {
    const { messageId } = params
    
    if (!messageId) {
      return NextResponse.json({ error: 'Message ID is required' }, { status: 400 })
    }

    const supabase = createServerSupabaseClient()
    
    // Get current user session from auth header
    const authHeader = req.headers.get('authorization')
    let user
    
    try {
      if (authHeader) {
        const { data: { user: authUser }, error: authError } = await supabase.auth.getUser(authHeader.replace('Bearer ', ''))
        if (!authError) user = authUser
      } else {
        const { data: { user: sessionUser }, error: sessionError } = await supabase.auth.getUser()
        if (!sessionError) user = sessionUser
      }
    } catch (e) {
      // Ignore auth errors
    }

    if (!user) {
      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
    }

    // First, get the message to verify ownership and get chat_id
    const { data: message, error: fetchError } = await supabase
      .from('messages')
      .select('id, chat_id, type, content')
      .eq('id', messageId)
      .single()

    if (fetchError) {
      if (fetchError.code === 'PGRST116') {
        return NextResponse.json({ error: 'Message not found' }, { status: 404 })
      }
      console.error('Error fetching message:', fetchError)
      return NextResponse.json({ error: 'Failed to fetch message' }, { status: 500 })
    }

    // Verify the user has access to this message through the chat
    const { data: chat, error: chatError } = await supabase
      .from('chats')
      .select('id, user_id, chat_type, book_id')
      .eq('id', message.chat_id)
      .single()

    if (chatError || !chat) {
      console.error('Error fetching chat:', chatError)
      return NextResponse.json({ error: 'Chat not found' }, { status: 404 })
    }

    // Check if user owns the chat (for standalone chats) or the book (for book chats)
    let hasAccess = false
    
    if (chat.chat_type === 'standalone') {
      // For standalone chats, user must own the chat
      hasAccess = chat.user_id === user.id
    } else if (chat.chat_type === 'book' && chat.book_id) {
      // For book chats, user must own the book
      hasAccess = await checkBookOwnership(supabase, chat.book_id, user.id)
    }

    if (!hasAccess) {
      console.log('Authorization failed:', {
        messageId,
        chatType: chat.chat_type,
        chatUserId: chat.user_id,
        currentUserId: user.id,
        bookId: chat.book_id
      })
      return NextResponse.json({ error: 'Unauthorized' }, { status: 403 })
    }

    // Delete the message
    const { error: deleteError } = await supabase
      .from('messages')
      .delete()
      .eq('id', messageId)

    if (deleteError) {
      console.error('Error deleting message:', deleteError)
      return NextResponse.json({ error: 'Failed to delete message' }, { status: 500 })
    }

    console.log('Message deleted successfully:', { messageId, chatId: message.chat_id })
    return NextResponse.json({ success: true, messageId })

  } catch (error) {
    console.error('Error in message deletion:', error)
    return NextResponse.json({ error: 'Internal server error' }, { status: 500 })
  }
}

// Helper function to check if user owns a book
async function checkBookOwnership(supabase: any, bookId: string, userId: string): Promise<boolean> {
  const { data: book, error } = await supabase
    .from('books')
    .select('id')
    .eq('id', bookId)
    .eq('user_id', userId)
    .single()

  return !error && !!book
}